home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 6 / MacMania 6.toast / / Multimedia & Desktop / VideoToolbox / VideoToolboxSources / SetPriority.c < prev    next >
Text File  |  1997-07-02  |  7KB  |  179 lines

  1. /*
  2. SetPriority.c
  3.  
  4. SetPriority(1);
  5. // do high priority stuff here
  6. SetPriority(0);
  7.  
  8. Get and set the processor priority. The Macintosh operating system
  9. normally leaves the processor priority at zero, allowing all interrupts.
  10. You can temporarily block interrupts by raising the processor priority.
  11. The highest level is 7, blocking all interrupts. This is useful for time
  12. critical tasks, such as running video animations, where your primary
  13. concern is video timing, and you're willing to miss AppleTalk and
  14. keyboard events. Note that while the processor priority is high the
  15. keyboard and mouse will be dead, so that it is essential that your
  16. program lower it back down to allow the user to regain control.
  17.  
  18. Note that it may be enough to raise priority from the normal 0 to 1,
  19. because that blocks all deferred tasks until you take priority back down
  20. to 0. See the Deferred Task Manager in the Inside Mac Processes book.
  21.  
  22. It's a strange fact, but interrupt priority on PPC Macs is controlled
  23. by the processor priority of the emulated 68K processor. And the only
  24. way to set or get the processor priority is to run (possibly emulated)
  25. 68K code that accesses the 68K Status Register, as we do here using the
  26. inline functions GetStatusRegister() and SetStatusRegister().
  27.  
  28. Apple's Technote 1001 explains that processor priority is not hardware
  29. implemented in the PowerPC and that in fact there is no legal way to set
  30. it from PPC code. The suggested work-around, for old code, is to call a
  31. bit of 68K code since the 68K emulator will then do the right thing,
  32. setting the effective priority. That's what we do here. When compiled as
  33. PowerPC code the function calls a 68K version of the routines to actual
  34. get and set the priority. Technote 1094 (on VM) gives some details about
  35. emulation of the priviledged 68K instructions that access the SR.
  36.  
  37. SetPriority and GetPriority are trivial and fast when compiled as 68K
  38. code. They incur the cost of a mixed-mode switch (to and fro) when
  39. run as PPC code, because the actual set/get of priority can only be done
  40. as 68K code. I think the mixed mode switch takes on the order of 100
  41. microseconds, but that's only a vague recollection.
  42.  
  43. SEE:
  44. http://devworld.apple.com/dev/technotes/tn/tn1001.html
  45. <http://devworld.apple.com/dev/technotes/tn/tn1094.html>
  46. http://devworld.apple.com/dev/techsupport/insidemac/PPCSoftware/PPCSoftware-14.html
  47.  
  48. ACKNOWLEDGEMENTS:
  49. Thanks for help from:
  50. Quinn "The Eskimo!" <http://devworld.apple.com/dev/geeks.html> 421080
  51. Bo3b Johnson, Apple Developer Technical Support 421080
  52.  
  53. HISTORY:
  54. 1989?    dgp    wrote it
  55. 8/1/91    dgp    introduced the inline functions as a way to isolate the machine code
  56.             part, and to make it compatible with MPW C as well as THINK C.
  57. 8/6/91    dgp    fixed definition of GetStatusRegister() to make it a legal prototype.
  58. 2/15/93    dgp    added SwapPriority().
  59. 7/29/94 dgp disable all code if compiling for PowerPC
  60. 4/13/97 dgp Made callable from PowerPC code.
  61. 4/15/97 dgp Mention deferred tasks.
  62. 4/17/97 dgp MakeDataExecutable
  63. 4/28/97 dgp Deleted an erronous comment above about User/Supervisor mode.
  64. */
  65. #include "VideoToolbox.h"
  66.  
  67. #if GENERATING68K
  68.     /* 68k inline functions supported by THINK, MPW, and CodeWarrior C. */
  69.     pascal short GetStatusRegister(void)=0x40d7;                    /* MOVE.W SR,(SP)    */
  70.     pascal void SetStatusRegister(short status)=0x46df;        /* MOVE.W (SP)+,SR    */
  71. #else
  72. #include <OSUtils.h>    // FlushCodeCacheRange
  73.     /* 68K code, as compiled by CodeWarrior C. */
  74.     short SetPriority68K[]=
  75.         {0x48E7,0x1800,0x282F,0x000C,0x7007,0xC880,0xE18C,0x554F
  76.         ,0x40D7,0x301F,0x3600,0x0243,0xF8FF,0x8644,0x3F03,0x46DF,0x4CDF
  77.         ,0x0018,0x4E74,0x0004,0x8B53,0x4554,0x5052,0x494F,0x5249,0x5459,0x0000};       
  78.     short GetPriority68K[]=
  79.         {0x2F03,0x7600,0x554F,0x40D7,0x301F,0x3600,0xE043
  80.         ,0x0243,0x0007,0x3003,0x48C0,0x2F40,0x0008,0x261F
  81.         ,0x4E75,0x8B47,0x4554,0x5052,0x494F,0x5249,0x5459,0x0000};        
  82.     enum {
  83.         setPriority68KProcInfo = kPascalStackBased | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))
  84.         ,getPriority68KProcInfo = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long)))
  85.     };
  86. #endif
  87.  
  88. pascal void SetPriority(long i)
  89. {
  90.     #if GENERATING68K
  91.         register short status;
  92.     
  93.         i &= 7;
  94.         i <<= 8;
  95.         status=GetStatusRegister();
  96.         status &= ~0x700;    // clear the priority bits
  97.         status |= i;            // insert new priority bits
  98.         SetStatusRegister(status);
  99.     #else
  100.         static Boolean firstTime=1;
  101.         if(firstTime){
  102.             MakeDataExecutable(SetPriority68K,sizeof(SetPriority68K));
  103.             firstTime=0;
  104.         }
  105.         CallUniversalProc((UniversalProcPtr)SetPriority68K,setPriority68KProcInfo,i);
  106.     #endif
  107. }
  108.  
  109. pascal long GetPriority(void)
  110. {
  111.     register short status=0;
  112.  
  113.     #if GENERATING68K
  114.         status=GetStatusRegister();
  115.         status >>= 8;
  116.         status &= 7;
  117.     #else
  118.         static Boolean firstTime=1;
  119.         if(firstTime){
  120.             MakeDataExecutable(GetPriority68K,sizeof(GetPriority68K));
  121.             firstTime=0;
  122.         }
  123.         status=CallUniversalProc((UniversalProcPtr)GetPriority68K,getPriority68KProcInfo);
  124.     #endif
  125.     return status;
  126. }
  127.  
  128. void SwapPriority(char *priority)
  129. {
  130.         char oldPriority;
  131.         
  132.         oldPriority=GetPriority();
  133.         SetPriority(*priority);
  134.         *priority=oldPriority;
  135. }
  136.  
  137. /*
  138. Compiled without A6 Stack frames (linker option) because the Linker won't get to
  139. fix up the zero field left by the compiler.
  140.  
  141. Hunk:    Kind=HUNK_GLOBAL_CODE  Name="SETPRIORITY"(1)  Size=54
  142. 00000000: 48E7 1800          MOVEM.L   D3/D4,-(A7)
  143. 00000004: 282F 000C          MOVE.L    $000C(A7),D4
  144. 00000008: 7007               MOVEQ     #$07,D0
  145. 0000000A: C880               AND.L     D0,D4
  146. 0000000C: E18C               LSL.L     #$8,D4
  147. 0000000E: 554F               SUBQ.W    #$2,A7
  148. 00000010: 40D7               MOVE      SR,(A7)
  149. 00000012: 301F               MOVE.W    (A7)+,D0
  150. 00000014: 3600               MOVE.W    D0,D3
  151. 00000016: 0243 F8FF          ANDI.W    #$F8FF,D3
  152. 0000001A: 8644               OR.W      D4,D3
  153. 0000001C: 3F03               MOVE.W    D3,-(A7)
  154. 0000001E: 46DF               MOVE      (A7)+,SR
  155. 00000020: 4CDF 0018          MOVEM.L   (A7)+,D3/D4
  156. 00000024: 4E74 0004          RTD       #$0004
  157. 00000028: 8B53 4554 5052     DC.B      $80+$0B, 'SETPRIORITY'
  158.           494F 5249 5459 
  159. 00000034: 0000           
  160.  
  161. Hunk:    Kind=HUNK_GLOBAL_CODE  Name="GETPRIORITY"(2)  Size=44
  162. 00000000: 2F03               MOVE.L    D3,-(A7)
  163. 00000002: 7600               MOVEQ     #$00,D3
  164. 00000004: 554F               SUBQ.W    #$2,A7
  165. 00000006: 40D7               MOVE      SR,(A7)
  166. 00000008: 301F               MOVE.W    (A7)+,D0
  167. 0000000A: 3600               MOVE.W    D0,D3
  168. 0000000C: E043               ASR.W     #$8,D3
  169. 0000000E: 0243 0007          ANDI.W    #$0007,D3
  170. 00000012: 3003               MOVE.W    D3,D0
  171. 00000014: 48C0               EXT.L     D0
  172. 00000016: 2F40 0008          MOVE.L    D0,$0008(A7)
  173. 0000001A: 261F               MOVE.L    (A7)+,D3
  174. 0000001C: 4E75               RTS
  175. 0000001E: 8B47 4554 5052     DC.B      $80+$0B, 'GETPRIORITY'
  176.           494F 5249 5459 
  177. 0000002A: 0000           
  178. */
  179.